home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / MIXTREE.PAK / MIXTREE.C < prev    next >
C/C++ Source or Header  |  1997-05-06  |  19KB  |  706 lines

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1993 - 1995  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE:   mixtree.c
  9. //
  10. //  PURPOSE:  Implement the windows procedure for the main application
  11. //    windows.  Also implement the generic message and command dispatchers.
  12. //
  13. //  FUNCTIONS:
  14. //    WndProc         - Processes messages for the main window.
  15. //    MsgCommand      - Handle the WM_COMMAND messages for the main window.
  16. //    MsgDestroy      - Handles the WM_DESTROY message by calling 
  17. //                      PostQuitMessage().
  18. //    MsgSize         - Handles WM_SIZE messages for main window; resizes
  19. //                      TreeView control.
  20. //    MsgPaint        - Handles WM_PAINT messages for main window.
  21. //    MsgNotify       - Handles WM_NOTIFY messages for main window sent by
  22. //                      TreeView control.
  23. //    MsgChangeBranch - Handles private message sent when user has selected
  24. //                      a different branch of the TreeView control
  25. //    CmdFill         - Fills the TreeView control.
  26. //    CmdDisplayAll   - Allows all destination lines to be displayed at once.
  27. //    CmdCollapseAny  - Allows the children of any item to be collapsed.
  28. //    CmdExit         - Handles the file exit command by calling destory 
  29. //                      window on the main window.
  30. //    CreateImageList - Create an Image List.
  31. //    CreateTreeView  - Create a TreeViewControl.
  32. //
  33. //  COMMENTS:
  34. //
  35.  
  36. #include <windows.h>                // required for all Windows applications.
  37. #include <windowsx.h>
  38. #include "globals.h"                // prototypes specific to this application.
  39.  
  40. // FUNCTION PROTOTYPES
  41.  
  42. HWND CreateTreeView(HWND hwndParent, int iID, DWORD dwStyle);
  43.  
  44. HIMAGELIST CreateImageList(HWND hwnd);
  45.  
  46. // Main window message table definition.
  47. MSD rgmsd[] =
  48. {
  49.     {WM_COMMAND,      MsgCommand},
  50.     {WM_DESTROY,      MsgDestroy},
  51.     {WM_CREATE,       MsgCreate},
  52.     {WM_SIZE,         MsgSize},
  53.     {WM_PAINT,        MsgPaint},
  54.     {WM_NOTIFY,       MsgNotify},
  55.     {PM_CHANGEBRANCH, MsgChangeBranch}
  56. };
  57.  
  58. MSDI msdiMain =
  59. {
  60.     sizeof(rgmsd) / sizeof(MSD),
  61.     rgmsd,
  62.     edwpWindow
  63. };
  64.  
  65. // Main window command table definition.
  66. CMD rgcmd[] =
  67. {
  68.     {IDM_EXIT,        CmdExit},
  69.     {IDM_ABOUT,       CmdAbout},
  70.     {IDM_FILL,        CmdFill},
  71.     {IDM_DISPLAYALL,  CmdDisplayAll},
  72.     {IDM_COLLAPSEANY, CmdCollapseAny}
  73. };
  74.  
  75. CMDI cmdiMain =
  76. {
  77.     sizeof(rgcmd) / sizeof(CMD),
  78.     rgcmd,
  79.     edwpWindow
  80. };
  81.  
  82. UINT uMixItems;                     // total number of TreeView items used
  83.  
  84. UINT      uNumMixers;               // number of mixer devices in system
  85. HMIXER    hMixer;                   // handle of mixer device
  86. UINT      uMixerID;                 // identifier for selected mixer
  87. MIXERCAPS MixerCaps;                // device capabilities of selected mixer
  88.  
  89. MIXITEMINFO amixii[MAXMIXITEMS];    // array of structs for associating mixer
  90.                                     // lines and controls with TreeView items.
  91. IMAGELISTINFO aImageInfo[IL_MAXIMAGES];  // info for entire image list
  92.  
  93.  
  94. //
  95. //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
  96. //
  97. //  PURPOSE:  Processes messages for the main window.
  98. //
  99. //  PARAMETERS:
  100. //    hwnd     - window handle
  101. //    uMessage - message number
  102. //    wparam   - additional information (dependant on message number)
  103. //    lparam   - additional information (dependant on message number)
  104. //
  105. //  RETURN VALUE:
  106. //    The return value depends on the message number.  If the message
  107. //    is implemented in the message dispatch table, the return value is
  108. //    the value returned by the message handling function.  Otherwise,
  109. //    the return value is the value returned by the default window procedure.
  110. //
  111. //  COMMENTS:
  112. //    Call the DispMessage() function with the main window's message dispatch
  113. //    information (msdiMain) and the message specific information.
  114. //
  115.  
  116. LRESULT CALLBACK WndProc(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  117. {
  118.     return DispMessage(&msdiMain, hwnd, uMessage, wparam, lparam);
  119. }
  120.  
  121.  
  122. //
  123. //  FUNCTION: MsgCommand(HWND, UINT, WPARAM, LPARAM)
  124. //
  125. //  PURPOSE: Handle the WM_COMMAND messages for the main window.
  126. //
  127. //  PARAMETERS:
  128. //    hwnd     - window handle
  129. //    uMessage - WM_COMMAND (Unused)
  130. //    GET_WM_COMMAND_ID(wparam, lparam)   - Command identifier
  131. //    GET_WM_COMMAND_HWND(wparam, lparam) - Control handle
  132. //
  133. //  RETURN VALUE:
  134. //    The return value depends on the message number.  If the message
  135. //    is implemented in the message dispatch table, the return value is
  136. //    the value returned by the message handling function.  Otherwise,
  137. //    the return value is the value returned by the default window procedure.
  138. //
  139. //  COMMENTS:
  140. //    Call the DispCommand() function with the main window's command dispatch
  141. //    information (cmdiMain) and the command specific information.
  142. //
  143.  
  144. #pragma argsused
  145. LRESULT MsgCommand(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  146. {
  147.     return DispCommand(&cmdiMain, hwnd, wparam, lparam);
  148. }
  149.  
  150. //
  151. //  FUNCTION: MsgCreate(HWND, UINT, WPARAM, LPARAM)
  152. //
  153. //  PURPOSE: Creates TreeView Control, and posts "Fill" message.
  154. //
  155. //  PARAMETERS:
  156. //
  157. //    hwnd      - Window handle  (Unused)
  158. //    uMessage  - Message number (Unused)
  159. //    wparam    - not used
  160. //    lparam    - not used
  161. //
  162. //  RETURN VALUE:
  163. //
  164. //    Always returns 0 - Message handled
  165. //
  166. //  COMMENTS:
  167. //
  168. //
  169.  
  170. #pragma argsused
  171. LRESULT MsgCreate(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  172. {
  173.     // Create the TreeView control with lines only
  174.     hwndTreeView = CreateTreeView(hwnd, 
  175.                                   0, 
  176.                                   TVS_HASLINES | 
  177.                                   // TVS_HASBUTTONS | TVS_LINESATROOT  |
  178.                                   WS_VISIBLE | WS_CHILD | WS_BORDER);
  179.   
  180.     if (hwndTreeView)
  181.     {
  182.         // set global variable for application menu handle
  183.         hMenu = GetMenu(hwnd);
  184.  
  185.         // initialize some menu items in the application menu
  186.         CheckMenuItem(hMenu, IDM_DISPLAYALL,  fDisplayAll  ?
  187.             MF_CHECKED : MF_UNCHECKED);
  188.         CheckMenuItem(hMenu, IDM_COLLAPSEANY, fCollapseAny ? 
  189.             MF_CHECKED : MF_UNCHECKED);
  190.  
  191.         // get handle of font used in TreeView control so we can use it, too      
  192.         hfTVFont = (HFONT)SendMessage(hwndTreeView, WM_GETFONT, 0, 0);
  193.     
  194.         // fill the TreeView control
  195.         PostMessage(hwnd, WM_COMMAND, IDM_FILL, 0);
  196.     }
  197.     else
  198.         // couldn't create TreeView control so exit
  199.         PostMessage(hwnd, WM_COMMAND, IDM_EXIT, 0);
  200.  
  201.     return 0;
  202. }
  203.  
  204. //
  205. //  FUNCTION: MsgDestroy(HWND, UINT, WPARAM, LPARAM)
  206. //
  207. //  PURPOSE: Calls PostQuitMessage(), cleans up image list.
  208. //
  209. //  PARAMETERS:
  210. //
  211. //    hwnd      - Window handle  (Unused)
  212. //    uMessage  - Message number (Unused)
  213. //    wparam    - Extra data     (Unused)
  214. //    lparam    - Extra data     (Unused)
  215. //
  216. //  RETURN VALUE:
  217. //
  218. //    Always returns 0 - Message handled
  219. //
  220. //  COMMENTS:
  221. //
  222. //
  223.  
  224. #pragma argsused
  225. LRESULT MsgDestroy(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  226. {
  227.     // Clean up the image list.
  228.  
  229.     if (hImageList)
  230.         ImageList_Destroy(hImageList);
  231.  
  232.     PostQuitMessage(0);
  233.     return 0;
  234. }
  235.  
  236. //
  237. //  FUNCTION: MsgSize(HWND, UINT, WPARAM, LPARAM)
  238. //
  239. //  PURPOSE: Resizes TreeView Control
  240. //
  241. //  PARAMETERS:
  242. //
  243. //    hwnd      - Window handle  (Unused)
  244. //    uMessage  - Message number (Unused)
  245. //    wparam    - Not used.
  246. //    lparam    - Not used.
  247. //
  248. //  RETURN VALUE:
  249. //
  250. //    Always returns 0 - Message handled
  251. //
  252. //  COMMENTS:
  253. //
  254. //
  255.  
  256. #pragma argsused
  257. LRESULT MsgSize(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  258. {
  259.     RECT rc;    // Client area rect
  260.  
  261.     // Figure the new client area
  262.  
  263.     GetClientRect(hwnd, &rc);
  264.  
  265.     // Resize the TreeView control
  266.  
  267.     if (hwndTreeView)
  268.         SetWindowPos(hwndTreeView,
  269.                      NULL,
  270.                      0, 0,
  271.                      rc.right / 3, rc.bottom,
  272.                      SWP_NOZORDER);
  273.  
  274.     return 0;
  275. }
  276.  
  277. //
  278. //  FUNCTION: MsgPaint(HWND, UINT, WPARAM, LPARAM)
  279. //
  280. //  PURPOSE: Paints text info area to right of TreeView control
  281. //
  282. //  PARAMETERS:
  283. //
  284. //    hwnd      - Window handle  (Unused)
  285. //    uMessage  - Message number (Unused)
  286. //    wparam    - Not used.
  287. //    lparam    - Not used.
  288. //
  289. //  RETURN VALUE:
  290. //
  291. //    Always returns 0 - Message handled
  292. //
  293. //  COMMENTS:
  294. //
  295. //
  296.  
  297. #pragma argsused
  298. LRESULT MsgPaint(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  299. {
  300.     PAINTSTRUCT ps;
  301.  
  302.     BeginPaint(hwnd, &ps);
  303.     DisplayItemInfo(hwnd, ps.hdc);
  304.     EndPaint(hwnd, &ps);
  305.  
  306.     return 0;
  307. }
  308.   
  309.  
  310. //
  311. //  FUNCTION: MsgNotify(HWND, UINT, WPARAM, LPARAM)
  312. //
  313. //  PURPOSE: Handles notifications from TreeView Control
  314. //
  315. //  PARAMETERS:
  316. //
  317. //    hwnd      - Window handle  (Unused)
  318. //    uMessage  - Message number (Unused)
  319. //    wparam    - control id
  320. //    lparam    - points to an NMHDR (Notify Message Header) which 
  321. //                is overloaded with a NM_TREEVIEW structure:
  322. //     
  323. //
  324. //  RETURN VALUE:
  325. //
  326. //    Always returns 0 - Message handled
  327. //
  328. //  COMMENTS:
  329. //
  330. //
  331. #pragma argsused
  332. LRESULT MsgNotify(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  333. {           
  334.     switch (((LPNMHDR)lparam)->code)   
  335.     {
  336.         case TVN_ITEMEXPANDING: 
  337.         {
  338.             HTREEITEM htiNew = ((LPNM_TREEVIEW)lparam)->itemNew.hItem;
  339.  
  340.             // take action if the new selection is not the current root and
  341.             // View.Display All has not been selected
  342.             if (htiNew && htiNew != htiCurrentRoot && !fDisplayAll)
  343.             {                          
  344.                 // see if the new item is the root of its branch
  345.                 if (!TreeView_GetParent(hwndTreeView, htiNew))                    
  346.                     // it's the root; collapse previous branch, expand this one
  347.                     PostMessage(hwnd, PM_CHANGEBRANCH, (UINT)htiNew, 0L);                                                                                   
  348.             }
  349.  
  350.         // only allow an item to expand while building the tree or switching destinations
  351.             // unless View.Collapse Any has been selected
  352.             if (!fExpandEnabled && !fCollapseAny)
  353.                 // don't allow item to expand  
  354.                 return 1;    
  355.  
  356.             break;
  357.         }
  358.  
  359.         case TVN_SELCHANGED:
  360.         {
  361.             TV_ITEM tviNew = ((LPNM_TREEVIEW)lparam)->itemNew;
  362.             HDC hdc;        
  363.                       
  364.             // remember the current selection if there is one
  365.             lCurrentItem = tviNew.hItem ? tviNew.lParam : MIXITEM_NOSELECTION;
  366.  
  367.             // display the current item's info
  368.             GetItemInfo(hwnd, lCurrentItem);            
  369.             hdc = GetDC(hwnd);
  370.             DisplayItemInfo(hwnd, hdc);
  371.             ReleaseDC(hwnd, hdc);           
  372.         
  373.             break;
  374.         }
  375.  
  376.         default:
  377.             break;
  378.     }
  379.  
  380.     return 0;
  381. }
  382.  
  383. //
  384. //  FUNCTION: MsgChangeBranch(HWND, UINT, WPARAM, LPARAM)
  385. //
  386. //  PURPOSE: Handles message sent when user selects a different branch of
  387. //           the TreeView control, collapsing the previous branch and
  388. //           expanding the new one.
  389. //
  390. //  PARAMETERS:
  391. //
  392. //    hwnd      - Window handle  (Unused)
  393. //    uMessage  - Message number (Unused)
  394. //    wparam    - HTREEITEM indicating root item of new branch
  395. //    lparam    - (Unused)
  396. //
  397. //     
  398. //
  399. //  RETURN VALUE:
  400. //
  401. //    Always returns 0 - Message handled
  402. //
  403. //  COMMENTS:
  404. //
  405. //
  406. #pragma argsused
  407. LRESULT MsgChangeBranch(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  408. {      
  409.     // enable expansion of TreeView control
  410.     fExpandEnabled = TRUE;
  411.        
  412.     // collapse the branch of the current root
  413.     TreeView_Expand(hwndTreeView, htiCurrentRoot, TVE_COLLAPSE);
  414.  
  415.     // make the new selection the current root
  416.     htiCurrentRoot = (HTREEITEM)wparam;
  417.  
  418.     // expand the branch of the new current root
  419.     ExpandBranch(htiCurrentRoot);
  420.  
  421.     // defeat expansion of TreeView control
  422.     fExpandEnabled = FALSE;
  423.  
  424.     return 0;
  425. }
  426.  
  427.  
  428. //
  429. //  FUNCTION: CmdFill(HWND, WORD, WORD, HWND)
  430. //
  431. //  PURPOSE: Fill TreeView Control will the lines and controls.
  432. //
  433. //  PARAMETERS:
  434. //    hwnd     - window handle
  435. //    wCommand - IDM_FILL
  436. //    wNotify  - Not Used.
  437. //    hwndCtrl - Not Used.
  438. //
  439. //  RETURN VALUE:
  440. //    Always 0.
  441. //
  442. //  COMMENTS:
  443. //    This calls the BuildMixerTree() function in MIXLINE.C to fill the
  444. //    TreeView control. The message to invoke this function is posted
  445. //    at startup in MsgCreate().
  446.  
  447. #pragma argsused
  448. LRESULT CmdFill(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  449. {
  450.     BuildMixerTree(hwnd);   
  451.                      
  452.     return 0;
  453. }
  454.  
  455.  
  456. //
  457. //  FUNCTION: CmdDisplayAll(HWND, WORD, WORD, HWND)
  458. //
  459. //  PURPOSE: Enables the ability to display all destination lines 
  460. //           simultaneously.
  461. //
  462. //  PARAMETERS:
  463. //    hwnd     - window handle
  464. //    wCommand - IDM_DISPLAYALL
  465. //    wNotify  - Not Used.
  466. //    hwndCtrl - Not Used.
  467. //
  468. //  RETURN VALUE:
  469. //    Always 0.
  470. //
  471. //  COMMENTS:
  472. //
  473. //
  474.  
  475. #pragma argsused
  476. LRESULT CmdDisplayAll(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  477. {
  478.     // toggle the flag
  479.     fDisplayAll ^= TRUE;
  480.  
  481.     // reset the current root to the root of the TreeView control
  482.     htiCurrentRoot = TreeView_GetRoot(hwndTreeView);
  483.  
  484.     if (fDisplayAll)   
  485.         // display all destination lines expanded
  486.         ExpandTreeView(); 
  487.     else 
  488.     {
  489.         HTREEITEM htiRoot = htiCurrentRoot;
  490.     
  491.         fExpandEnabled = TRUE;
  492.        
  493.         // display first destination line expanded
  494.         ExpandBranch(htiCurrentRoot);
  495.        
  496. #pragma warn -pia
  497.         // display all other destination lines collapsed
  498.         while (htiRoot = TreeView_GetNextSibling(hwndTreeView, htiRoot))
  499.             TreeView_Expand(hwndTreeView, htiRoot, TVE_COLLAPSE);
  500. #pragma warn .pia
  501.           
  502.         fExpandEnabled = FALSE;
  503.     }
  504.  
  505.     CheckMenuItem(hMenu, IDM_DISPLAYALL, fDisplayAll ? MF_CHECKED : MF_UNCHECKED);
  506.     return 0;
  507. }
  508.  
  509.  
  510. //
  511. //  FUNCTION: CmdCollapseAny(HWND, WORD, WORD, HWND)
  512. //
  513. //  PURPOSE: Enables the ability to collapse the children of any item.
  514. //
  515. //  PARAMETERS:
  516. //    hwnd     - window handle
  517. //    wCommand - IDM_COLLAPSEANY
  518. //    wNotify  - Not Used.
  519. //    hwndCtrl - Not Used.
  520. //
  521. //  RETURN VALUE:
  522. //    Always 0.
  523. //
  524. //  COMMENTS:
  525. //    
  526. //
  527.  
  528. #pragma argsused
  529. LRESULT CmdCollapseAny(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  530. {
  531.     // toggle the flag
  532.     fCollapseAny ^= TRUE;
  533.  
  534.     CheckMenuItem(hMenu, IDM_COLLAPSEANY, fCollapseAny ? MF_CHECKED : MF_UNCHECKED);
  535.     return 0;
  536. }
  537.  
  538.  
  539. //
  540. //  FUNCTION: CmdExit(HWND, WORD, WORD, HWND)
  541. //
  542. //  PURPOSE: Exit the application.
  543. //
  544. //  PARAMETERS:
  545. //    hwnd     - The window.
  546. //    wCommand - IDM_EXIT (unused)
  547. //    wNotify  - Notification number (unused)
  548. //    hwndCtrl - NULL (unused)
  549. //
  550. //  RETURN VALUE:
  551. //    Always returns 0 - command handled.
  552. //
  553. //  COMMENTS:
  554. //
  555. //
  556.  
  557. #pragma argsused
  558. LRESULT CmdExit(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  559. {
  560.     DestroyWindow(hwnd);
  561.     return 0;
  562. }
  563.  
  564. //
  565. //  FUNCTION: CreateImageList(HWND hwnd)
  566. //
  567. //  PURPOSE: Create an ImageList for use with the TreeView.
  568. //
  569. //  PARAMETERS:
  570. //    hwnd - handle of parent window.
  571. //
  572. //  RETURN VALUE:
  573. //    On Success: Handle to the Image List
  574. //    On Failure: NULL
  575. //
  576. //  COMMENTS:
  577. //    The bitmaps for the image list are stored in the resources
  578. //    of this application. For this example, each bitmap is a
  579. //    separate resource. The background (mask) color of the bitmaps
  580. //    is white - RGB (255,255,255), which is what the image list
  581. //    will automagically use as a mask as explained below.
  582. //
  583. //    Even though the bitmaps in the resources are 32x32 pixels,
  584. //    we are only using the upper left 20x12 portion, as this is the
  585. //    minimum bounding rectangle to fit the little teensy pictures.
  586. //
  587. //    To change the size of the images, edit both the bitmaps,
  588. //    and change the parameters to ImageList_Create.
  589. //
  590.  
  591. #pragma argsused
  592. HIMAGELIST CreateImageList(HWND hwnd)
  593. {
  594.     HIMAGELIST hIL;       // Handle to ImageList
  595.     HBITMAP    hBitmap;   // Handle to a bitmap
  596.     int i;
  597.  
  598.     // Create the Image List
  599.     hIL = ImageList_Create(20,     // X size of one image
  600.                            12,     // Y size of one image
  601.                             TRUE,   // Masked images
  602.                            IL_MAXIMAGES, // number of images in list
  603.                            0);     // No "growing" bitmaps in this list.
  604.  
  605.     if (!hIL) 
  606.         return NULL;
  607.    
  608.     // put bitmap resource identifiers into info array
  609.     aImageInfo[IL_DESTLINE].uBitmapID = IDB_DESTLINE;
  610.     aImageInfo[IL_SRCLINE].uBitmapID  = IDB_SRCLINE;
  611.     aImageInfo[IL_CUSTOM].uBitmapID   = IDB_CUSTOM;
  612.     aImageInfo[IL_METER].uBitmapID    = IDB_METER;
  613.     aImageInfo[IL_SWITCH].uBitmapID   = IDB_SWITCH;
  614.     aImageInfo[IL_NUMBER].uBitmapID   = IDB_NUMBER;
  615.     aImageInfo[IL_SLIDER].uBitmapID   = IDB_SLIDER;
  616.     aImageInfo[IL_FADER].uBitmapID    = IDB_FADER;
  617.     aImageInfo[IL_TIME].uBitmapID     = IDB_TIME;
  618.     aImageInfo[IL_LIST].uBitmapID     = IDB_LIST;  
  619.  
  620.     // Add Each bitmap to the ImageList
  621.     for (i = 0; i < IL_MAXIMAGES; i++)
  622.     {    
  623.         // ImageList_AddMasked will add the bitmap, and treat every
  624.         // pixel that is (in this example) white as a "transparent" pixel,
  625.         // since we specified TRUE for fMask in the above call to
  626.         // ImageList_Create.
  627.  
  628.         hBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(aImageInfo[i].uBitmapID));
  629.         if (hBitmap)
  630.         {
  631.             aImageInfo[i].uImageIndex =
  632.                 ImageList_AddMasked(hIL, hBitmap, RGB(255,255,255));
  633.             DeleteObject (hBitmap);
  634.         }
  635.     }
  636.   
  637.     // Paranoid checking to make sure everything was added successfully.
  638.     if (ImageList_GetImageCount(hIL) < IL_MAXIMAGES)
  639.     {
  640.         ImageList_Destroy(hIL);
  641.         hIL = NULL;
  642.  
  643.         for (i = 0; i < IL_MAXIMAGES; i++)
  644.             aImageInfo[i].uImageIndex = 0;
  645.     }
  646.  
  647.     // Success! 
  648.     return hIL;
  649. }
  650.  
  651. //
  652. //  FUNCTION: CreateTreeView(HWND hwndParent, int iID, DWORD dwStyle)
  653. //
  654. //  PURPOSE: Create a TreeView control
  655. //
  656. //  PARAMETERS:
  657. // 
  658. //    hwndParent - Parent of the TreeView.
  659. //    iID        - ID of the TreeView.
  660. //    dwStyle    - Style bits of the TreeView.
  661. //
  662. //  RETURN VALUE:
  663. //    On Success: Handle to the TreeView
  664. //    On Failure: NULL
  665. //
  666. //  COMMENTS:
  667. //
  668. //    The call to InitCommonControls is required once per application
  669. //    lifetime. It is OK to move this to init.c, but for the
  670. //    cut-and-pastibility of this sample, the call is placed here.
  671. //
  672.  
  673. HWND CreateTreeView(HWND hwndParent, int iID, DWORD dwStyle)
  674. {
  675.     RECT rc;      // Client rect of parent
  676.     HWND hwnd;    // Handle to TreeView
  677.  
  678.     // This registers the TreeView class.
  679.     InitCommonControls();
  680.  
  681.     // Get the client area of the parent.
  682.     GetClientRect(hwndParent, &rc);
  683.  
  684.     // Create the TreeView control.
  685.     hwnd = CreateWindowEx(0,                        // Ex style
  686.                           WC_TREEVIEW,              // Class
  687.                           "",                       // Dummy Text
  688.                           dwStyle,                  // Style
  689.                           0, 0,                     // Use all of
  690.                           rc.right, rc.bottom,      // client area.
  691.                           hwndParent,               // Parent
  692.                           (HMENU)iID,               // ID
  693.                           hInst,                    // Instance
  694.                           NULL);                    // No extra
  695.  
  696.     // Create the ImageList for this TreeView
  697.     hImageList = CreateImageList(hwnd);
  698.  
  699.     // Attach ImageList to TreeView
  700.     if (hImageList && hwnd)
  701.         (void) TreeView_SetImageList(hwnd, hImageList, 0);
  702.  
  703.     // Return the window handle
  704.     return hwnd;
  705. }
  706.